#pragma once
#include "..\Controls\ListCtrl.h"
#include "..\DataManager\PasswordManager.h"
#include "PasswordCategoryTree.h"


class CPasswordListCtrl : public CListCtrlData<CPasswordProfile*>
{
public:
		DECLARE_WND_CLASS( _T( "PasswordListCtrl" ) )
	CPasswordListCtrl()
	{
		m_bDragging = FALSE;
	}
	~CPasswordListCtrl()
	{}
public:
	BEGIN_MSG_MAP(CPasswordListCtrl)   
		MSG_WM_MOUSEMOVE(OnMouseMove)
		MSG_WM_LBUTTONUP(OnLButtonUp)
		REFLECTED_NOTIFY_CODE_HANDLER(LVN_BEGINDRAG,OnLvnBeginDrag)
		DEFAULT_REFLECTION_HANDLER()
	END_MSG_MAP()  
	LRESULT OnLvnBeginDrag    (int nCode, LPNMHDR pnmh, BOOL& bHandled)
	{
		m_nDragIndex = ((NM_LISTVIEW *)pnmh)->iItem;
		POINT pt;
		pt.x = 8;
		pt.y = 8;
		m_pDragImage = CreateDragImage (m_nDragIndex, &pt);
		ATLASSERT (m_pDragImage);
		// changes the cursor to the drag image (DragMove() is still required in 
		// OnMouseMove())
		m_pDragImage.BeginDrag (0, CPoint (8, 8));
		m_pDragImage.DragEnter (GetDesktopWindow (), ((NM_LISTVIEW *)pnmh)->ptAction);
		// set dragging flag
		m_bDragging = TRUE;
		m_hDropItem = NULL;
		m_nDropIndex = -1;
		m_pDropWnd = this->m_hWnd;
		// capture all mouse messages
		SetCapture ();
		return 0L;
	}
	CImageList CreateDragImage(int nItem, LPPOINT lpPoint)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return CImageList((HIMAGELIST)::SendMessage(m_hWnd, LVM_CREATEDRAGIMAGE, nItem, (LPARAM)lpPoint));
	}
	
	void OnLButtonUp(UINT uMsg, CPoint ptx)
	{
		if (m_bDragging)
		{
			// release mouse capture
			::ReleaseCapture ();
			m_bDragging = FALSE;
			// end dragging
			m_pDragImage.DragLeave (GetDesktopWindow ());
			m_pDragImage.EndDrag ();

			CPoint pt (ptx);
			ClientToScreen (&pt);
			HWND pDropWnd = WindowFromPoint (pt);
			ATLASSERT (pDropWnd);
			::ScreenToClient(pDropWnd,&pt);
			TCHAR szClassName[MAX_PATH] = { 0 };
			GetClassName(pDropWnd, szClassName, MAX_PATH);
			//MessageBox(szClassName);
			if ( _tcsicmp(szClassName, L"CPasswordCategoryTree") == 0 )
			{			
				CPasswordCategoryTree artTree; 
				artTree.Attach(pDropWnd);
				DropItemOnTree(artTree);
				artTree.Detach();
				artTree.m_hWnd = NULL;
				
			}
			//else if (pDropWnd->IsKindOf (RUNTIME_CLASS (CListCtrl)))
			else if (_tcsicmp(szClassName,WC_LISTVIEW) == 0)
			{			
				//DropItemOnList ((CListViewCtrl)pDropWnd);
			}
			// get the CWnd pointer of the window that is under the mouse cursor
			//CWnd* pDropWnd = WindowFromPoint (pt);
			//ATLASSERT (pDropWnd);
			//// if window is CTreeCtrl
			//if (pDropWnd->IsKindOf (RUNTIME_CLASS (CTreeCtrl)))
			//	DropItemOnTree ((CTreeCtrl*)pDropWnd);
			//// if window is CListCtrl
			//else if (pDropWnd->IsKindOf (RUNTIME_CLASS (CListCtrl)))
			//	DropItemOnList ((CListCtrl*)pDropWnd);
		}

	}
	void DropItemOnTree (CPasswordCategoryTree& pDropTree)
	{
		// remove hilight from drop target
		pDropTree.SelectDropTarget (NULL);
		if(!m_hDropItem)
			return;
		/*CArticleCategoryTree* pTree = static_cast<CArticleCategoryTree*>(pDropTree);
		if(!pTree)
		{
			return;
		}*/
		CPasswordProfile* pPf = NULL;
		GetItemData(m_nDragIndex,pPf);
		if(NULL != pPf)
			pDropTree.AcceptDrag(m_hDropItem,pPf->m_nID );

		// insert item into CTreeCtrl
		//HTREEITEM hNewItem = pDropTree->InsertItem (&tvis);
		//ATLASSERT (hNewItem);
		// select the new item we just inserted
		//ATLVERIFY (pDropTree->SelectItem (hNewItem));
		// delete the original item (move operation)
		ATLVERIFY (DeleteItem (m_nDragIndex));
	}
	
	void OnMouseMove(UINT uMsg, CPoint ptx)
	{
		
		if (m_bDragging)
		{
			CPoint pt (ptx);
			ClientToScreen (&pt);
			// move the drag image
			ATLVERIFY (m_pDragImage.DragMove (pt));
			// unlock window updates
			ATLVERIFY (m_pDragImage.DragShowNolock (FALSE));

			// get the CWnd pointer of the window that is under the mouse cursor
			HWND pDropWnd = WindowFromPoint (pt);
			ATLASSERT (pDropWnd);
			// if we drag outside current window
			if (pDropWnd != m_pDropWnd)
			{
				// turn off hilight for drop target in tree control
				if (m_hDropItem)
				{
					(CTreeViewCtrl(m_pDropWnd)).SelectDropTarget (NULL);
					m_hDropItem = NULL;
				}
				// turn off hilight for drop target in list control
				if (m_nDropIndex != -1)
				{
					//CListCtrl* pList = (CListCtrl*)m_pDropWnd;
					CListCtrlData lCtrl;
					lCtrl.Attach(m_pDropWnd);
					//ATLVERIFY (lCtrl.SetItemState (m_nDropIndex, 0, LVIS_DROPHILITED));
					// redraw item
					//ATLVERIFY ((CListCtrlData(m_pDropWnd)).RedrawItems (m_nDropIndex, m_nDropIndex));
					lCtrl.UpdateWindow ();
					lCtrl.Detach();
					m_nDropIndex = -1;
				}
			}

			// save current window pointer
			m_pDropWnd = pDropWnd;

			// convert from screen coordinates to drop target client coordinates
			//CWindow pWin = CWindow(pDropWnd);
			::ScreenToClient(pDropWnd,&pt);
			TCHAR szClassName[MAX_PATH] = { 0 };
			GetClassName(pDropWnd, szClassName, MAX_PATH);
			//MessageBox(szClassName);
			if ( _tcsicmp(szClassName, L"CPasswordCategoryTree") == 0 )
			// if window is CTreeCtrl
			//if (pDropWnd->IsKindOf (RUNTIME_CLASS (CTreeCtrl)))
			//if(pWin.GetWndClassName() == WC_TREEVIEW)
			{			
				UINT uFlags;
				// get the item that is below cursor
				m_hDropItem = ((CTreeViewCtrl)pDropWnd).HitTest (pt, &uFlags);
				// highlight it
				((CTreeViewCtrl)pDropWnd).SelectDropTarget (m_hDropItem);
			}
			//else if (pDropWnd->IsKindOf (RUNTIME_CLASS (CListCtrl)))
			else if (_tcsicmp(szClassName, L"PasswordListCtrl") == 0)
			{			
				//UINT uFlags;
				//CListCtrl* pList = (CListCtrl*)pDropWnd;
				CListCtrlData lCtrl;
				lCtrl.Attach(m_pDropWnd);
				// turn off hilight for previous drop target
				//(CListCtrlData(m_pDropWnd)).SetItemState (m_nDropIndex, 0, LVIS_DROPHILITED);
				// redraw previous item
				//(CListCtrlData(m_pDropWnd)).RedrawItems (m_nDropIndex, m_nDropIndex);
				
				// get the item that is below cursor
				int iSubItem;
				lCtrl.HitTest (pt,m_nDropIndex,iSubItem);
				// highlight it
				//(CListCtrlData(m_pDropWnd)).SetItemState (m_nDropIndex, LVIS_DROPHILITED, LVIS_DROPHILITED);
				// redraw item
				//(CListCtrlData(m_pDropWnd)).RedrawItems (m_nDropIndex, m_nDropIndex);
				lCtrl.UpdateWindow ();
			}
			// lock window updates
			m_pDragImage.DragShowNolock (TRUE);
		}
		
	}

	

protected:

	CImageList m_pDragImage;
	BOOL		m_bDragging;
	int			m_nDragIndex, m_nDropIndex;
	HTREEITEM	m_hDropItem;
	HWND		m_pDropWnd;

};